package com.xiaoniu.forum.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaoniu.forum.common.constant.RedisKeyConstant;
import com.xiaoniu.forum.common.utils.CountUtils;
import com.xiaoniu.forum.common.utils.PageUtils;
import com.xiaoniu.forum.dao.*;
import com.xiaoniu.forum.entity.*;
import com.xiaoniu.forum.entity.vo.*;
import com.xiaoniu.forum.form.AppCommentForm;
import com.xiaoniu.forum.form.AppPageForm;
import com.xiaoniu.forum.form.AppTopicForm;
import com.xiaoniu.forum.service.AppCommunityService;
import com.xiaoniu.forum.service.CommunityTopicCommentService;
import com.xiaoniu.forum.service.CommunityTopicService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class AppCommunityServiceImpl implements AppCommunityService{

    @Autowired
    private CommunityDao communityDao;

    @Autowired
    private CommunityCategoryDao communityCategoryDao;

    @Autowired
    private CommunityTopicCategoryDao communityTopicCategoryDao;

    @Autowired
    private CommunityTopicDao communityTopicDao;

    @Autowired
    private CommunityTopicService communityTopicService;

    @Autowired
    private CommunityTopicCommentDao communityTopicCommentDao;

    @Autowired
    private CommunityTopicStatusDao communityTopicStatusDao;

    @Autowired
    private MemberDao memberDao;

    @Autowired
    private CommunityTopicCommentService communityTopicCommentService;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Autowired
    private CountUtils countUtils;

    @Override
    //@CachePut(value = "indexDataList")
    public List<AppCommunityIndexVo> getIndexList() {
        Date date1 = new Date();
        //构造社区分类查询条件
        QueryWrapper<CommunityCategoryEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("status","1");
        wrapper.select("id","name");
        wrapper.orderByDesc("sort");
        //查询社区分类列表
        List<CommunityCategoryEntity> communityCategoryEntityList = communityCategoryDao.selectList(wrapper);

        //构造社区查询条件
        QueryWrapper<CommunityEntity> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("status","1");
        wrapper1.select("id","name","list_img","category_id");
        wrapper1.orderByDesc("sort");
        //查询社区列表
        List<CommunityEntity> communityEntityList = communityDao.selectList(wrapper1);

        List<AppCommunityIndexVo> list = new ArrayList<>();

        //封装
        for (CommunityCategoryEntity communityCategoryEntity : communityCategoryEntityList) {
            //新建VO
            AppCommunityIndexVo appCommunityIndexVo = new AppCommunityIndexVo();
            //设置社区分类名
            appCommunityIndexVo.setId(communityCategoryEntity.getId());
            appCommunityIndexVo.setCommunityCategoryName(communityCategoryEntity.getName());
            //给Vo封装板块
            for (CommunityEntity communityEntity : communityEntityList) {
                if (StringUtils.pathEquals(communityCategoryEntity.getId(),communityEntity.getCategoryId())) {
                    AppCommunityVo appCommunityVo = new AppCommunityVo();
                    //设置属性
                    appCommunityVo.setId(communityEntity.getId());
                    appCommunityVo.setName(communityEntity.getName());
                    appCommunityVo.setCommunityImg(communityEntity.getListImg());
                    //添加到Vo的集合
                    appCommunityIndexVo.getCommunityList().add(appCommunityVo);
                }
            }
            //添加数据到集合
            list.add(appCommunityIndexVo);
        }

        Date date2 = new Date();
        System.out.println((date2.getTime() - date1.getTime()));

        //将封装的数据返回
        return list;
    }

    @Override
    public AppCommunityInfoVo getCommunityInfoById(String id) {
        QueryWrapper<CommunityEntity> wrapper = new QueryWrapper<>();
        //构造条件
        wrapper.eq("id",id);
        wrapper.eq("status","1");
        wrapper.orderByDesc("sort");
        //条件查询
        CommunityEntity communityEntity = communityDao.selectOne(wrapper);

        //封装
        AppCommunityInfoVo communityInfoVo = new AppCommunityInfoVo();
        BeanUtils.copyProperties(communityEntity,communityInfoVo);
        communityInfoVo.setImgUrl(communityEntity.getListImg());

        return communityInfoVo;
    }

    @Override
    public List<AppTopicCategoryVo> getTopicCategoryById(String id) {
        QueryWrapper<CommunityTopicCategoryEntity> wrapper = new QueryWrapper<>();

        //构造条件
        wrapper.eq("community_id",id);
        wrapper.eq("status","1");
        wrapper.orderByDesc("sort");

        //条件查询
        List<CommunityTopicCategoryEntity> communityTopicCategoryEntityList = communityTopicCategoryDao.selectList(wrapper);

        List<AppTopicCategoryVo> list = new ArrayList<>();

        //封装
        for (CommunityTopicCategoryEntity communityTopicCategoryEntity : communityTopicCategoryEntityList) {
            AppTopicCategoryVo appTopicCategoryVo = new AppTopicCategoryVo();

            BeanUtils.copyProperties(communityTopicCategoryEntity,appTopicCategoryVo);

            list.add(appTopicCategoryVo);
        }

        return list;
    }

    @Override
    public List<AppCommunityTopTopicVo> getTopicTopsById(String id) {
        return communityTopicDao.getTopicTops(id);
    }

    @Override
    public PageUtils getTopicsById(String communityId, String topicCategoryId, AppPageForm pageForm) {
        QueryWrapper<CommunityTopicEntity> wrapper = new QueryWrapper<>();

        //构造条件
        wrapper.eq("community_id",communityId)
               .eq("status","1")
               .eq("pass","1")
               .eq("type","1")
               .orderByDesc("create_time");

        if (!StringUtils.isEmpty(topicCategoryId)){
            wrapper.eq("topic_category_id",topicCategoryId);
        }

        Page page = new Page();
        page.setSize(pageForm.getPageSize());
        page.setCurrent(pageForm.getPageIndex());

        Page dataPage = communityTopicDao.selectPage(page, wrapper);

        List communityTopicEntityList = dataPage.getRecords();

        //如果查询结果没有数据 直接返回
        if (communityTopicEntityList.isEmpty()){
            return null;
        }

        List<AppCommunityTopicVo> list = new ArrayList<>();

        //批量获取用户ID 和 状态ID 存储到集合 以便查询
        List<String> memberIds = new ArrayList<>();;
        List<String> ids = new ArrayList<>();;

        for (Object obj : communityTopicEntityList) {

            CommunityTopicEntity communityTopicEntity = (CommunityTopicEntity) obj;

            String memberId = communityTopicEntity.getUserId();

            memberIds.add(memberId);
            ids.add(communityTopicEntity.getId());
        }


        //查询数据库
        List<MemberEntity> memberEntityList = memberDao.selectBatchIds(memberIds);
        List<CommunityTopicStatusEntity> communityTopicStatusEntityList = communityTopicStatusDao.selectBatchIds(ids);


        //封装
        for (Object obj : communityTopicEntityList) {

            CommunityTopicEntity communityTopicEntity = (CommunityTopicEntity) obj;

            AppCommunityTopicVo appCommunityTopicVo = new AppCommunityTopicVo();
            appCommunityTopicVo.setContent(communityTopicEntity.getThreadsText());
            BeanUtils.copyProperties(communityTopicEntity,appCommunityTopicVo);
            //封装话题内容
            appCommunityTopicVo.setContent(communityTopicEntity.getThreadsText());

            boolean flag = false;

            for (CommunityTopicStatusEntity communityTopicStatusEntity : communityTopicStatusEntityList) {
                if (StringUtils.pathEquals(communityTopicEntity.getId(),communityTopicStatusEntity.getThreadsId()))
                    //判断此话题状态是否为公告或是置顶 是的话则跳过封装
                    if ("1".equals(communityTopicStatusEntity.getTop())||"1".equals(communityTopicStatusEntity.getNotice())){
                        flag = true;
                        break;
                    }else {
                        appCommunityTopicVo.setStatus(communityTopicStatusEntity);
                    }
            }

            //如果此话题状态是否为公告或是置顶 取消封装
            if (flag){
                continue;
            }

            for (MemberEntity memberEntity : memberEntityList) {
                if (StringUtils.pathEquals(memberEntity.getId(),communityTopicEntity.getUserId())){
                    appCommunityTopicVo.setMemberId(memberEntity.getId());
                    appCommunityTopicVo.setMemberNickname(memberEntity.getNickname());
                    appCommunityTopicVo.setMemberAvatar(memberEntity.getAvatar());
                }
            }

            list.add(appCommunityTopicVo);

        }

        page.setRecords(list);

        return new PageUtils(page);
    }

    @Override
    public AppCommunityTopicInfoVo getTopicInfoById(String id) {
        //根据id查询
        CommunityTopicEntity communityTopicEntity = communityTopicDao.selectById(id);

        AppCommunityTopicInfoVo appCommunityTopicInfoVo = new AppCommunityTopicInfoVo();

        //封装话题信息
        BeanUtils.copyProperties(communityTopicEntity,appCommunityTopicInfoVo);
        appCommunityTopicInfoVo.setContent(communityTopicEntity.getThreadsText());

        //封装用户信息
        MemberEntity memberEntity = memberDao.selectById(communityTopicEntity.getUserId());

        appCommunityTopicInfoVo.setMemberId(memberEntity.getId());
        appCommunityTopicInfoVo.setMemberNickname(memberEntity.getNickname());
        appCommunityTopicInfoVo.setMemberAvatar(memberEntity.getAvatar());

        //将话题查看数加入缓存
        countUtils.countByRedis(id);

        return appCommunityTopicInfoVo;
    }

    @Override
    public PageUtils getTopicCommentsById(String id,AppPageForm pageForm) {
        long begin = System.currentTimeMillis();

        //TODO 前端传入分页数据
        Page page = new Page(pageForm.getPageIndex(), pageForm.getPageSize());

        QueryWrapper<CommunityTopicCommentEntity> wrapper = new QueryWrapper<>();

        //编写条件
        wrapper.eq("threads_id",id);
        wrapper.eq("status","1");
        wrapper.eq("pass","1");
        wrapper.orderByDesc("create_time");
        wrapper.isNull("parent_id");

        communityTopicCommentDao.selectPage(page, wrapper);

        if (page.getRecords().isEmpty()){
            return null;
        }

        List parents = page.getRecords();

        List<AppCommunityCommentListVo> list = new ArrayList<>();

        for (Object obj : parents) {
            CommunityTopicCommentEntity parent = (CommunityTopicCommentEntity) obj;

            AppCommunityCommentListVo appCommunityCommentListVo = new AppCommunityCommentListVo();
            AppCommunityCommentParentVo appCommunityCommentParentVo = new AppCommunityCommentParentVo();

            //封装父评论
            BeanUtils.copyProperties(parent,appCommunityCommentParentVo);
            appCommunityCommentParentVo.setContent(parent.getReplyText());

            //封装父评论用户数据
            if (!StringUtils.isEmpty(parent.getUserId())){
                MemberEntity memberEntity = memberDao.selectById(parent.getUserId());

                appCommunityCommentParentVo.setMemberId(memberEntity.getId());
                appCommunityCommentParentVo.setMemberNickname(memberEntity.getNickname());
                appCommunityCommentParentVo.setMemberAvatar(memberEntity.getAvatar());
            }

            /**
             * 构造条件 为了查询子评论
             */
            //清空条件
            wrapper.clear();

            //编写条件
            wrapper.eq("threads_id",id);
            wrapper.eq("status","1");
            wrapper.eq("pass","1");
            wrapper.orderByDesc("create_time");
            //根据父评论id 查询子评论
            wrapper.eq("parent_id",parent.getId());
            wrapper.last("limit 0,2");

            List<CommunityTopicCommentEntity> childrens = communityTopicCommentDao.selectList(wrapper);

            //遍历封装
            for (CommunityTopicCommentEntity children : childrens) {
                AppCommunityCommentChildrenVo appCommunityCommentChildrenVo = new AppCommunityCommentChildrenVo();

                //封装子评论数据
                BeanUtils.copyProperties(children,appCommunityCommentChildrenVo);
                appCommunityCommentChildrenVo.setContent(children.getReplyText());

                //封装子评论用户数据
                if (!StringUtils.isEmpty(children.getUserId())) {
                    MemberEntity memberEntity = memberDao.selectById(children.getUserId());
                    appCommunityCommentChildrenVo.setMemberId(children.getUserId());
                    appCommunityCommentChildrenVo.setMemberNickname(memberEntity.getNickname());
                }

                if (!StringUtils.isEmpty(children.getBackUserId())) {
                    MemberEntity backMemberEntity = memberDao.selectById(children.getBackUserId());
                    appCommunityCommentChildrenVo.setBackMemberId(children.getBackUserId());
                    appCommunityCommentChildrenVo.setBackMemberNickname(backMemberEntity.getNickname());
                }

                appCommunityCommentListVo.getChildren().add(appCommunityCommentChildrenVo);

            }

            wrapper.clear();
            wrapper.eq("parent_id",parent.getId());

            Integer count = communityTopicCommentDao.selectCount(wrapper);
            appCommunityCommentListVo.setBackCount(count);

            appCommunityCommentListVo.setParent(appCommunityCommentParentVo);
            list.add(appCommunityCommentListVo);
        }

        long end = System.currentTimeMillis();

        System.out.println(end-begin);

        page.setRecords(list);

        return new PageUtils(page);
    }

    @Override
    public void checkin(String communityId,String memberId) {

        redisTemplate.opsForValue().set("community:"+communityId+":checkin:"+memberId,"checkin",20L, TimeUnit.SECONDS);
    }

    @Override
    public boolean isCheckin(String communityId,String memberId) {
        Object str = redisTemplate.opsForValue().get("community:"+communityId+":checkin:"+memberId);
        if (!StringUtils.isEmpty(str)){
            return true;
        }else {
            return false;
        }
    }

    /**
     * 评论
     *
     * @param commentForm 前端表单
     */
    @Override
    public void saveComment(AppCommentForm commentForm) {
        CommunityTopicCommentEntity communityTopicCommentEntity = new CommunityTopicCommentEntity();

        //公共封装
        communityTopicCommentEntity.setThreadsId(commentForm.getTopicId());
        communityTopicCommentEntity.setReplyText(commentForm.getContent());
        communityTopicCommentEntity.setUserId(commentForm.getMemberId());
        //如果有值的话 封装
        if (!StringUtils.isEmpty(commentForm.getBackMemberId()))
            communityTopicCommentEntity.setBackUserId(commentForm.getBackMemberId());
        if (!StringUtils.isEmpty(commentForm.getParentId()))
            communityTopicCommentEntity.setParentId(commentForm.getParentId());

        communityTopicCommentEntity.setPass("2");

        communityTopicCommentDao.insert(communityTopicCommentEntity);

    }

    @Override
    public void saveTopic(AppTopicForm topicForm) {
        CommunityTopicEntity communityTopicEntity = new CommunityTopicEntity();

        BeanUtils.copyProperties(topicForm,communityTopicEntity);
        communityTopicEntity.setThreadsText(topicForm.getContent());
        communityTopicEntity.setType("1");
        communityTopicEntity.setPass("2");
        communityTopicEntity.setUserId(topicForm.getMemberId());

        communityTopicService.save(communityTopicEntity);

        CommunityTopicStatusEntity topicStatusEntity = new CommunityTopicStatusEntity();
        topicStatusEntity.setThreadsId(communityTopicEntity.getId());

        communityTopicStatusDao.insert(topicStatusEntity);

    }

    /**
     * 根据用户id分页查询话题（根据创建时间倒序）
     */
    @Override
    public PageUtils listTopicByUserId(String userId, Page page) {
        QueryWrapper<CommunityTopicEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",userId);
        queryWrapper.eq("pass",1);
        page.addOrder(OrderItem.desc("create_time"));
        Page resultPage = communityTopicDao.selectPage(page, queryWrapper);
        return new PageUtils(resultPage);
    }

    /**
     * 根据用户id分页查询评论（根据创建时间倒序）
     * 注意：这里只查询通过审核的话题
     */
    @Override
    public PageUtils listCommentByUserId(String userId, Page page) {
        QueryWrapper<CommunityTopicCommentEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",userId);
        queryWrapper.eq("pass",1);
        page.addOrder(OrderItem.desc("create_time"));
        Page resultPage = communityTopicCommentDao.selectPage(page, queryWrapper);
        List<AppBaseCommentVo> baseCommentVos = new ArrayList<>();
        resultPage.getRecords().forEach((comment)->{
            AppBaseCommentVo appBaseCommentVo = new AppBaseCommentVo();
            BeanUtils.copyProperties(comment,appBaseCommentVo);
            baseCommentVos.add(appBaseCommentVo);
        });
        resultPage.setRecords(baseCommentVos);
        return new PageUtils(resultPage);
    }

    /**
     * 获取社区分类 封装成发布联查VO
     *
     * @return
     */
    @Override
    public List<AppPublishOptionVo> getCommunityCategoryForOption() {
        QueryWrapper<CommunityCategoryEntity> wrapper = new QueryWrapper<>();
        wrapper.select("id","name");
        wrapper.eq("status","1");
        wrapper.orderByDesc("sort");

        List<CommunityCategoryEntity> communityCategoryEntityList = communityCategoryDao.selectList(wrapper);

        List<AppPublishOptionVo> list = new ArrayList<>();

        for (CommunityCategoryEntity communityCategoryEntity : communityCategoryEntityList) {
            AppPublishOptionVo appPublishOptionVo = new AppPublishOptionVo();
            appPublishOptionVo.setText(communityCategoryEntity.getName());
            appPublishOptionVo.setValue(communityCategoryEntity.getId());

            list.add(appPublishOptionVo);
        }

        return list;
    }

    /**
     * 根据id查询社区 封装成发布联查VO
     *
     * @param id
     * @return
     */
    @Override
    public List<AppPublishOptionVo> getCommunityForOptionById(String id) {
        QueryWrapper<CommunityEntity> wrapper = new QueryWrapper<>();
        wrapper.select("id","name");
        wrapper.eq("status","1");
        wrapper.eq("category_id",id);
        wrapper.orderByDesc("sort");

        List<CommunityEntity> communityEntityList = communityDao.selectList(wrapper);

        List<AppPublishOptionVo> list = new ArrayList<>();

        for (CommunityEntity communityEntity : communityEntityList) {
            AppPublishOptionVo appPublishOptionVo = new AppPublishOptionVo();
            appPublishOptionVo.setText(communityEntity.getName());
            appPublishOptionVo.setValue(communityEntity.getId());

            list.add(appPublishOptionVo);
        }

        return list;
    }

    /**
     * 根据id查询话题分类 封装成发布联查VO
     *
     * @param id
     * @return
     */
    @Override
    public List<AppPublishOptionVo> getTopicCategoryForOptionById(String id) {
        QueryWrapper<CommunityTopicCategoryEntity> wrapper = new QueryWrapper<>();
        wrapper.select("id","name");
        wrapper.eq("status","1");
        wrapper.eq("community_id",id);
        wrapper.orderByDesc("sort");

        List<CommunityTopicCategoryEntity> communityTopicCategoryEntityList = communityTopicCategoryDao.selectList(wrapper);

        List<AppPublishOptionVo> list = new ArrayList<>();

        for (CommunityTopicCategoryEntity communityTopicCategoryEntity : communityTopicCategoryEntityList) {
            AppPublishOptionVo appPublishOptionVo = new AppPublishOptionVo();
            appPublishOptionVo.setText(communityTopicCategoryEntity.getName());
            appPublishOptionVo.setValue(communityTopicCategoryEntity.getId());

            list.add(appPublishOptionVo);
        }

        return list;
    }

    /**
     * 根据评论id查询评论详情
     * @param id
     * @return
     */
    @Override
    public AppCommunityCommentListVo getCommentInfoById(String id) {
        QueryWrapper<CommunityTopicCommentEntity> wrapper = new QueryWrapper<>();

        //查询父评论
        wrapper.eq("id",id);
        wrapper.eq("status","1");
        wrapper.eq("pass","1");
        CommunityTopicCommentEntity parentComment = communityTopicCommentDao.selectOne(wrapper);
        if (parentComment == null){
            return  null;
        }

        //清空条件
        wrapper.clear();

        //查询子评论
        wrapper.eq("parent_id",id);
        wrapper.eq("status","1");
        wrapper.eq("pass","1");
        wrapper.orderByDesc("create_time");
        List<CommunityTopicCommentEntity> childrenCommentList = communityTopicCommentDao.selectList(wrapper);

        AppCommunityCommentListVo communityTopicListVo = new AppCommunityCommentListVo();

        //将查询出来的数据中的用户id提取出来，减少与数据库之间的交互
        //set集合元素不能重复
        HashSet<String> idSet = new HashSet<>();

        //添加父评论用户id
        idSet.add(parentComment.getUserId());
        //添加子评论用户id
        for (CommunityTopicCommentEntity communityTopicCommentEntity : childrenCommentList) {
            idSet.add(communityTopicCommentEntity.getUserId());
            if (!StringUtils.isEmpty(communityTopicCommentEntity.getBackUserId())){
                idSet.add(communityTopicCommentEntity.getBackUserId());
            }
        }

        //批量查询用户
        List<MemberEntity> memberEntityList = memberDao.selectBatchIds(idSet);
        if (memberEntityList.isEmpty()){
            return null;
        }

        //封装父评论
        AppCommunityCommentParentVo parentVo = new AppCommunityCommentParentVo();
        //封装评论数据
        BeanUtils.copyProperties(parentComment,parentVo);
        parentVo.setContent(parentComment.getReplyText());
        //封装用户
        memberEntityList.forEach( member ->{
            if (StringUtils.pathEquals(member.getId(),parentComment.getUserId())){
                parentVo.setMemberAvatar(member.getAvatar());
                parentVo.setMemberNickname(member.getNickname());
                parentVo.setMemberId(member.getId());
            }
        });

        //封装子评论
        childrenCommentList.forEach(comment ->{
            AppCommunityCommentChildrenVo childrenVo = new AppCommunityCommentChildrenVo();
            //封装评论数据
            BeanUtils.copyProperties(comment,childrenVo);
            childrenVo.setContent(comment.getReplyText());
            //封装用户数据
            memberEntityList.forEach( member ->{
                //封装发布此评论用户的数据(一定有)
                if (StringUtils.pathEquals(member.getId(),comment.getUserId())){
                    childrenVo.setMemberNickname(member.getNickname());
                    childrenVo.setMemberId(member.getId());
                    childrenVo.setMemberAvatar(member.getAvatar());
                }
                //封装此评论回复用户的数据(不一定有)
                if (StringUtils.pathEquals(member.getId(),comment.getBackUserId())){
                    childrenVo.setBackMemberNickname(member.getNickname());
                    childrenVo.setBackMemberId(member.getId());
                }
            });
            communityTopicListVo.getChildren().add(childrenVo);
        });

        communityTopicListVo.setParent(parentVo);


        return communityTopicListVo;
    }


}
